package cc.magicjson.synthesis.chain;



import cc.magicjson.synthesis.context.DiscountContext;
import cc.magicjson.synthesis.model.Order;
import cc.magicjson.synthesis.model.User;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 积分折扣检查器，负责计算积分抵扣金额
 */
public class PointsDiscountChecker extends DiscountChecker {

    private static final String DISCOUNT_TYPE = "POINTS";
    private static final String POINTS_USED_KEY = "POINTS_USED";

    // 积分兑换比例：多少积分兑换1元
    private final int pointsPerYuan;

    public PointsDiscountChecker(int pointsPerYuan) {
        this.pointsPerYuan = pointsPerYuan;
    }

    @Override
    protected boolean doCheck(DiscountContext context) {
        Order order = context.getOrder();
        User user = order.getUser();

        // 如果用户选择不使用积分，则跳过积分折扣计算
        if (!order.isUsePoints() || user.getPoints() <= 0) {
            return true;
        }

        // 计算积分可抵扣的最大金额
        BigDecimal maxDiscountAmount = BigDecimal.valueOf(user.getPoints())
                .divide(BigDecimal.valueOf(pointsPerYuan), 2, RoundingMode.HALF_UP);

        // 实际抵扣金额不能超过订单金额
        BigDecimal actualDiscountAmount = maxDiscountAmount.min(order.getFinalAmount());

        // 计算实际使用的积分
        int pointsUsed = actualDiscountAmount.multiply(BigDecimal.valueOf(pointsPerYuan))
                .setScale(0, RoundingMode.DOWN).intValue();

        // 如果有积分可用，则应用折扣
        if (pointsUsed > 0) {
            // 重新计算精确的折扣金额
            actualDiscountAmount = BigDecimal.valueOf(pointsUsed)
                    .divide(BigDecimal.valueOf(pointsPerYuan), 2, RoundingMode.HALF_UP);

            // 更新订单金额
            BigDecimal newFinalAmount = order.getFinalAmount().subtract(actualDiscountAmount);
            order.setFinalAmount(newFinalAmount);

            // 更新订单总折扣金额
            BigDecimal newDiscountAmount = order.getDiscountAmount().add(actualDiscountAmount);
            order.setDiscountAmount(newDiscountAmount);

            // 记录使用的积分，用于回滚
            context.setAttribute(POINTS_USED_KEY, pointsUsed);

            // 添加折扣明细
            context.addDiscountDetail(DISCOUNT_TYPE, actualDiscountAmount);

            // 暂时不扣减用户积分，在支付成功后再扣减
        }

        return true; // 继续处理下一个折扣
    }

    @Override
    protected void doRollback(DiscountContext context) {
        // 获取使用的积分
        Integer pointsUsed = context.getAttribute(POINTS_USED_KEY);
        if (pointsUsed == null || pointsUsed == 0) {
            return; // 没有使用积分，不需要回滚
        }

        // 计算需要回滚的金额
        BigDecimal rollbackAmount = BigDecimal.valueOf(pointsUsed)
                .divide(BigDecimal.valueOf(pointsPerYuan), 2, RoundingMode.HALF_UP);

        Order order = context.getOrder();

        // 恢复订单金额
        order.setFinalAmount(order.getFinalAmount().add(rollbackAmount));

        // 恢复订单折扣金额
        order.setDiscountAmount(order.getDiscountAmount().subtract(rollbackAmount));

        // 从折扣明细中移除
        context.getDiscountDetails().remove(DISCOUNT_TYPE);
    }
}
